package net.zisen.cloud.order.service;

import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import lombok.extern.log4j.Log4j2;
import net.zisen.cloud.base.msg.ResultMsg;
import net.zisen.cloud.goods.client.GoodsClient;
import net.zisen.cloud.goods.model.Goods;
import net.zisen.cloud.order.dao.OrderDao;
import net.zisen.cloud.order.model.Order;
import net.zisen.cloud.wallet.client.WalletClient;
import org.beetl.sql.core.SQLManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Optional;
import java.util.UUID;

/**
 * @author tim/278002989@qq.com
 * @Classname OrderServiceImpl
 * @Description TODO
 * @Date 2019-05-17 16:09
 */
@Service
@Log4j2
public class OrderServiceImpl implements OrderService {


    @Autowired
    private OrderDao dao;

    @Autowired
    private SQLManager manager;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private WalletClient walletClient;

    /**
     * 添加订单
     *
     * @param uid
     * @param goodsId
     * @param quality
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 60, isolation = Isolation.READ_COMMITTED)
    @LcnTransaction
    public ResultMsg<Order> addOrder(Long uid, Long goodsId, Integer quality) throws Exception {
        if (!Optional.of(uid).isPresent() || !Optional.of(goodsId).isPresent() || !Optional.of(quality).isPresent() || quality < 1) {
            throw new Exception("参数错误");
        }
        ResultMsg updateResult = goodsClient.updateQuality(goodsId, quality);
        if (!Optional.of(updateResult).isPresent()) {
            throw new Exception("更新库存失败");
        } else if (!updateResult.isSuccess()) {
            return updateResult;
        }
        ResultMsg<Goods> goodsMsg = goodsClient.goodsDetail(goodsId);
        if (!Optional.of(goodsMsg).isPresent() || !goodsMsg.isSuccess()) {
            return ResultMsg.fail().resultMsg("获取商品信息失败！");
        }
        Goods goods = goodsMsg.getData();
        Order order = Order.builder()
                .addTime(new Date())
                .editTime(new Date())
                .state(Order.State.NEW.getState())
                .num(UUID.randomUUID().toString())
                .totalAmount(goods.getPrice().multiply(new BigDecimal(quality)))
                .uid(uid)
                .build();
        int inserted = manager.insert(order);
        log.info("插入记录条数：{} 订单：{}", inserted, order);
        if (inserted > 0) {
            return ResultMsg.ok().data(order);
        }
        throw new Exception("创建订单失败");
    }

    /**
     * 支付订单
     *
     * @param orderNum
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 60, isolation = Isolation.READ_COMMITTED)
    @LcnTransaction
    public ResultMsg payOrder(String orderNum) throws Exception {
        Order order = this.manager.query(Order.class).andEq("num", orderNum).single();
        if (order == null || !order.getState().equals(Order.State.NEW.getState())) {
            return ResultMsg.fail().resultMsg("当前状态无法支付，请刷新订单状态！");
        }
        //查询钱包月
        ResultMsg<BigDecimal> amountResult = walletClient.checkWalletBalance(order.getUid());
        if (!Optional.of(amountResult).isPresent() || !amountResult.isSuccess()) {
            return amountResult;
        }
        if (amountResult.getData().compareTo(order.getTotalAmount()) < 0) {
            return ResultMsg.fail().resultMsg("钱包余额不足！");
        }
        //扣除钱包金额
        ResultMsg deductResult = walletClient.deduct(order.getUid(), order.getTotalAmount(), orderNum, "订单支付");
        if (!Optional.of(deductResult).isPresent() || !deductResult.isSuccess()) {
            throw new Exception("扣除金额失败");
        }
        order.setState(Order.State.PAID.getState());
        this.manager.updateById(order);
        return ResultMsg.ok().resultMsg("支付订单成功！");
    }

    /**
     * 创建并支付订单
     *
     * @param uid
     * @param goodsId
     * @param quality
     * @return {@link ResultMsg}
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class, timeout = 60, isolation = Isolation.READ_COMMITTED)
    public ResultMsg addAddPayOrder(Long uid, Long goodsId, Integer quality) throws Exception {
        return null;
    }
}
